//Janus解释语言 
#include<iostream>
#include<fstream>
#include<sstream>
#include<vector>
#include<set>
#include<map>
#include<cstdlib>
#include<ctime>
#include<cctype>
#include<functional>
#define dp(a)
using namespace std;

string ops[1024];
int on=0;
string JANpost;
map<string,short> fcl;
clock_t ct;

struct types{
	string str;
	int _int;
	char ty;
	FILE *f;
};

struct r{
};

map<string,function<types(string&)>> tokens; // 改为引用传参
map<string,types> vmap;

static unsigned int janus_seed=time(0);

// 类型转换函数实现
types bcmint(const types &t){
    types r;
    r.ty='i';
    switch(t.ty){
        case 's': r._int=atoi(t.str.c_str()); break;
        case 'c': r._int=t._int; break;
        case 'b': r._int=t._int?1:0; break;
        case 'p': r._int=(intptr_t)&vmap[t.str]; break;
        default: r._int=t._int;
    }
    return r;
}

types bcmstring(const types &t){
    types r;
    r.ty='s';
    switch(t.ty){
        case 'i': r.str=to_string(t._int); break;
        case 'c': r.str=string(1, (char)t._int); break;
        case 'b': r.str=t._int?"true":"false"; break;
        case 'p': r.str="[ptr]"+t.str; break;
        default: r.str=t.str;
    }
    return r;
}

types bcmchar(const types &t){
    types r;
    r.ty='c';
    switch(t.ty){
        case 'i': r._int=(char)(t._int%256); break;
        case 's': r._int=!t.str.empty()?t.str[0]:0; break;
        case 'b': r._int=t._int?'1':'0'; break;
        default: r._int=t._int;
    }
    return r;
}

types bcmbool(const types &t){
    types r;
    r.ty='b';
    switch(t.ty){
        case 'i': r._int=(t._int!=0); break;
        case 's': r._int=!t.str.empty(); break;
        case 'c': r._int=(t._int!=0); break;
        case 'p': r._int=(vmap.find(t.str)!=vmap.end()); break;
        default: r._int=!!t._int;
    }
    return r;
}

types bcmptr(const types &t){
    types r;
    r.ty='p';
    switch(t.ty){
        case 's': r.str=t.str; break;
        case 'i': r.str=to_string(t._int); break;
        default: r.str=to_string((intptr_t)&t);
    }
    return r;
}

types bcmfunc(const types &t){
    types r;
    r.ty='f';
    if(vmap.find(t.str)!=vmap.end()&&vmap[t.str].ty=='f'){
        r._int=vmap[t.str]._int;
    }else{
        cerr<<"Not a function:"<<t.str<<endl;
        r.ty='e';
    }
    return r;
}

char chcl(char a){
	if(isdigit(a)||isalpha(a)||a<0||a=='['||a=='_'||a=='$'||a=='.')return 'a';
	else if(a=='#'||a=='{')return '#';
	else return 'e';
}

int ling=0;

void cut(){
    for(int i=ling;i<on;i++){
        string &currentOp = ops[i];
        if(currentOp.empty() || currentOp=="Debug") continue;
        
        string newOp;
        bool instr = false;
        char quote = 0;
        char lastType = 0;
        
        for(size_t j=0;j<currentOp.size();j++){
            char ch = currentOp[j];
            if(!instr && (ch == '\"' || ch == '\'')){
                instr = true;
                quote = ch;
                newOp += ch;
                lastType = 'e';
                continue;
            }
            if(instr && ch == quote && (j==0 || currentOp[j-1] != '\\')){
                instr = false;
                quote = 0;
            }
            
            if(!instr){
                char ct = chcl(ch);
                if(ct != lastType && j!=0){
                    newOp += ' ';
                    lastType = ct;
                }
                if(j==0) lastType = ct;
            }
            newOp += ch;
        }
        currentOp = newOp;
    }
}

char shift(char ch){
	switch(ch){
        case 'a':return '\a';
        case 'b':return '\b';
        case 'f':return '\f';
        case 'n':return '\n';
        case 'r':return '\r';
        case 't':return '\t';
        case 'v':return '\v';
        case '\\':return '\\';
        case '\'':return '\'';
        case '"':return '\"';
        case 'e':return '\033';
        case 's':return ' ';
        case 'x':return 'x';
        default:return ch;
	}
}

string parse_escape(const string &s){
    string res;int ssz=s.size();
    for(size_t i=0;i<ssz;i++){
        if(s[i]=='\\'&&i+1<s.size()){
            res+=shift(s[i+1]);
            ++i;
        }else{
            res+=s[i];
        }
    }
    return res;
}

types explain();types co_explain(int&);
types pexpl(string &line){
    if(line.empty())return types();
    
    // 提取第一个token
    size_t pos = line.find_first_not_of(' ');
    if(pos == string::npos) return types();
    
    size_t end = line.find(' ', pos);
    string sop = (end == string::npos) ? line.substr(pos) : line.substr(pos, end-pos);
    
    // 更新line为剩余部分
    line = (end == string::npos) ? "" : line.substr(end+1);
    
    if(sop.empty())return types();
    
    if(sop[0]=='#'){
        return types();
    }else if(sop[0]=='\''){
        types t;
        t._int=parse_escape(sop.substr(1,sop.size()-2))[0];
        t.ty='c';
        return t;
    }else if(sop[0]=='\"'){
        types t;
        t.str=parse_escape(sop.substr(1,sop.size()-2));
        t.ty='s';
        return t;
    }else if(isdigit(sop[0])){
        types t;
        t._int=(atoi(sop.data()));
        t.ty='i';
        return t;
    }else{
        // 函数调用处理
        if(tokens.find(sop) == tokens.end()) {
            pan:
            if(sop[0]=='['){
                sop=sop.data()+1;
                string temp_line = sop;
                types t = pexpl(temp_line);
                if(t.ty == 's') sop = t.str;
                goto pan;
            }
            if(vmap.find(sop)==vmap.end()){
                cerr << "Undefined token: " << sop << endl;
                cerr<<"That line :"<<ops[ling]<<"\n";
                return types();
            }else{
                if(vmap[sop].ty=='f'){
                    int l=ling;
                    ling=vmap[sop]._int;
                    // 创建参数副本
                    string &args = line;
                    int bi=atoi(vmap[sop].str.data());
                    for(int i=1;i<=bi+1;i++){
                        vmap["var"+to_string(i)]=pexpl(args);
                    }
                    
                    types t=explain();
                    ling=l+1;
                    return t;
                }else if(vmap[sop].ty=='C'){
                    
                    // 创建参数副本
                    string &args = line;
                    int bi=atoi(vmap[sop].str.data());
                    for(int i=1;i<=bi+1;i++){
                        vmap["var"+to_string(i)]=pexpl(args);
                    }
                    
                    types t=co_explain(vmap[sop]._int);
                    return t;
				}else return vmap[sop];
            }
        }
        else{
            return tokens[sop](line);
        }
    }
}

types ret;

void init(){
	tokens["func"]=[](string&){
		static string temp;
		int i=1;
		while(i){
			stringstream ss(ops[++ling]);
			ss>>temp;
			if(temp=="func"||temp=="while"||temp=="until"||temp=="if"){
				i++;
			}else if(temp=="}"){
				i--;
			}
		}
		return types();
	};
	tokens["print"]=[](string& line){
		types t;
		while(!line.empty()){
			t=pexpl(line);
			switch(t.ty){
				case 's': cout<<t.str; break;
				case 'c': cout<<char(t._int); break;
				case 'i': cout<<t._int; break;
				case 'b': cout<<(t._int?"true":"false"); break;
				case 'v': cout<<"()"; break;
				case 'p': /*call the class 's output function*/break;
			}
		}
		return t;
	};
	tokens["Debug"]=[](string&){return types();};
	tokens["let"]=[](const string&op){
	    stringstream ss(op);
	    string vn;
	    ss>>vn;
	    pan:
		if(vn[0]=='['){
			vn=vn.data()+1;
			vn=vmap[vn].str;
	    	goto pan;
		}
	    string ve;
	    getline(ss,ve);
	    ve.erase(0,ve.find_first_not_of(" "));//trim
	    return vmap[vn]=pexpl(ve);
	};
	tokens["+"]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		t1.str+=t2.str;
		t1._int+=t2._int;
	    return t1;
	};
	tokens["-"]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		t1._int-=t2._int;
	    return t1;
	};
	tokens["*"]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		t1._int*=t2._int;
	    return t1;
	};
	tokens["/"]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		t1._int/=t2._int;
	    return t1;
	};
	tokens["if"]=[](string& line){
		types t=pexpl(line);
		switch(t.ty){
			case 's': t._int=!t.str.empty(); break;
			default: t._int=t._int;
		}
		t.ty='b';
		if(!t._int){
			int k=1;
			while(k){
				ling++;
				stringstream ss(ops[ling]);
				ss>>t.str;
				k+=t.str=="if";
				k+=t.str=="while";
				k-=t.str=="}";
			}
		}
	    return t;
	};
	tokens["}"]=[](string&){dp("c");return types();};
	tokens["while"]=[](string& line){
	    int start=ling;
	    while(1){
	        ling=start;
	        string cond = line;
	        types c=pexpl(cond);
	        
	        if((c.ty=='i'&&!c._int) || (c.ty=='b'&&!c._int) || (c.ty=='s'&&c.str.empty())){
	            break;
	        }
	        
	        int cl=start+1;
	        int bc=1;
	        while(cl<on&&bc>0){
	            string&co=ops[cl];
	            if(co=="}")bc--;
	            else if(co.find("{")!=string::npos)bc++;
	            ling=cl;
	            string temp = co;
	            pexpl(temp);
	            cl++;
	        }
	    }
	    
	    int k=1;
		while(k){
			ling++;
			stringstream ss(ops[ling]);
			types t;
			ss>>t.str;
			k+=(t.str=="if");
			k+=(t.str=="while");
			k-=(t.str=="}");
		}
	    return types();
	};
	tokens["true"]=[](string&){
		types t;
		t.ty='b';
		t._int=1;
		return t;
	};
	tokens["false"]=[](string&){
		types t;
		t.ty='b';
		t._int=0;
		return t;
	};
	tokens[">"]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		types r;r.ty='b';r._int=t1._int>t2._int;
		return r;
	};
	tokens["<"]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		types r;r.ty='b';r._int=t1._int<t2._int;
		return r;
	};
	tokens[">="]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		types r;r.ty='b';r._int=t1._int>=t2._int;
		return r;
	};
	tokens["<="]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		types r;r.ty='b';r._int=t1._int<=t2._int;
		return r;
	};
	tokens["!"]=[](string& line){
		types t=pexpl(line);
		types r;r.ty='b';r._int=!t._int;
		return r;
	};
	tokens["&&"]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		types r;r.ty='b';r._int=t1._int&&t2._int;
		return r;
	};
	tokens["||"]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		types r;r.ty='b';r._int=t1._int||t2._int;
		return r;
	};
	tokens["&"]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		t1._int&=t2._int;
		return t1;
	};
	tokens["|"]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		t1._int|=t2._int;
		return t1;
	};
	tokens["^"]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		t1._int^=t2._int;
		return t1;
	};
	tokens["%"]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		if(t2._int)t1._int%=t2._int;
		else cerr<<"Mod zero";
		return t1;
	};
	tokens["=="]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		types r;r.ty='b';
		r._int=(t1.ty==t2.ty)&&(t1.ty=='i'?t1._int==t2._int:t1.str==t2.str);
		return r;
	};
	tokens["!="]=[](string& line){
		types t1=pexpl(line);
		types t2=pexpl(line);
		types r;r.ty='b';
		r._int=!( (t1.ty==t2.ty)&&(t1.ty=='i'?t1._int==t2._int:t1.str==t2.str) );
		return r;
	};
	tokens["ret"]=[](string& line){
		ret=pexpl(line);
		throw r();
		return types();
	};
	tokens["]"]=[](string& line){
		string str;
		if(!line.empty()) str = line.substr(0, line.find(' '));
		pan:
		if(str[0]=='['){
			str=str.data()+1;
			string temp_line = str;
			types t = pexpl(temp_line);
			if(t.ty == 's') str = t.str;
	    	goto pan;
		}
		types t;
		t.ty='p';
		t.str=str;
		return t;
	};
	tokens["JANpost"]=[](string&){
		types t;
		t.ty='s';
		t.str=JANpost;
		return t;
	};
	tokens["WIN32"]=[](string&){
		types t;
		t.ty='b';
		#ifdef _WIN32
		t._int=1;
		#else
		t._int=0;
		#endif
		return t;
	};
	tokens["shell"]=[](string& line){
		types t;
		string cmd;
		if(!line.empty()) cmd = line;
		t._int=system(pexpl(cmd).str.data());
		t.ty='i';
		return t;
	};
	tokens["scan"]=[](string& line){
		types t;
		while(!line.empty()){
			string prs = line.substr(0, line.find(' '));
			pan:
			if(prs[0]=='['){
				prs=prs.data()+1;
				string temp_line = prs;
				types t = pexpl(temp_line);
				if(t.ty == 's') prs = t.str;
		    	goto pan;
			}
			switch(vmap[prs].ty){
				case 's': cin>>vmap[prs].str; break;
				case 'c':{
					char ch;
					cin>>ch;
					vmap[prs]._int=ch;
					}break;
				case 'i': cin>>vmap[prs]._int; break;
				case 'b': 
					cin>>vmap[prs].str;
					vmap[prs]._int=(vmap[prs].str=="true"?1:0);
					break;
			}
			line = line.substr(prs.size());
			while(!line.empty() && line[0]==' ') line.erase(0,1);
		}
		return t;
	};
	tokens["input"]=[](string&){
		types t;
		getline(cin,t.str);
		t.ty='s';
		return t;
	};
	tokens["bcmint"]=[](string& line){ return bcmint(pexpl(line)); };
	tokens["bcmstr"]=[](string& line){ return bcmstring(pexpl(line)); };
	tokens["bcmchar"]=[](string& line){ return bcmchar(pexpl(line)); };
	tokens["bcmbool"]=[](string& line){ return bcmbool(pexpl(line)); };
	tokens["bcmptr"]=[](string& line){ return bcmptr(pexpl(line)); };
	tokens["bcmfunc"]=[](string& line){ return bcmfunc(pexpl(line)); };
	tokens["new"]=[](string& line){
		char vcl=pexpl(line)._int;
		int vnum=pexpl(line)._int;
		string bstr=string(": ")+to_string(rand())+" $";
		for(int i=0;i<vnum;i++){
			vmap[bstr+to_string(i)].ty=vcl;
		}
		types t;
		t.ty='p';
		t.str=bstr+"0";
	    return t;
	};
	tokens["padd"]=[](string& line){
		types arr=pexpl(line);
		int offset=pexpl(line)._int;
		size_t pos=arr.str.find_last_of('$');
		if(pos==string::npos){
			cerr<<"Invalid array address"<<endl;
			return arr;
		}
		string base=arr.str.substr(0,pos+1);
		int index=stoi(arr.str.substr(pos+1));
		types new_addr;
		new_addr.ty='p';
		new_addr.str=base+to_string(index+offset);
		return new_addr;
	};
	tokens["srand"]=[](string& line){
	    types sd=pexpl(line);
	    if(sd.ty=='i'){
	        janus_seed=sd._int;
	    }else{
	        cerr<<"\'srand\' requires integer seed\n";
	    }
	    return types();
	};
	tokens["rand"]=[](string&){
	    janus_seed=janus_seed*214013+2531011;
	    types r;
	    r.ty='i';
	    r._int=(janus_seed>>16)&0x7FFF;
	    return r;
	};
	tokens["open"]=[](string& line){
		types t;
		string fname=pexpl(line).str;
		string mode=pexpl(line).str;
		FILE* fp=fopen(fname.c_str(),mode.c_str());
		if(!fp){
			cerr<<"Open failed:"<<fname<<endl;
			t.ty='e';
			return t;
		}
		t.ty='o';
		t.f=fp;
		return t;
	};
	tokens["out"]=[](string& line){
		types ft=pexpl(line);
		if(ft.ty!='o'){
			cerr<<"Invalid file handle"<<endl;
			return types();
		}
		FILE* fp=ft.f;
		if(!fp)return types();
		
		while(!line.empty()){
			string token = line.substr(0, line.find(' '));
			types pt=pexpl(token);
			string content;
			switch(pt.ty){
				case 's': content=pt.str; break;
				case 'i': content=to_string(pt._int); break;
				case 'c': content=string(1,pt._int); break;
				case 'b': content=(pt._int?"true":"false"); break;
				default: content="";
			}
			fputs(content.c_str(),fp);
			line = line.substr(token.size());
			while(!line.empty() && line[0]==' ') line.erase(0,1);
		}
		return types();
	};
	tokens["close"]=[](string& line){
		types t=pexpl(line);
		if(t.ty=='o'){
			FILE* fp=t.f;
			if(fp)fclose(fp);
		}
		return types();
	};
	tokens["in"]=[](string& line){
		FILE* fp=pexpl(line).f;
		if(!fp||feof(fp))return types();
		
		while(!line.empty()){
			string var = line.substr(0, line.find(' '));
			types &v=vmap[var];
			char buf[256];
			if(v.ty=='s'){
				fgets(buf,sizeof(buf),fp);
				v.str=string(buf);
				if(!v.str.empty()&&v.str.back()=='\n')
					v.str.pop_back();
			}else{
				fscanf(fp,"%d",&v._int);
			}
			line = line.substr(var.size());
			while(!line.empty() && line[0]==' ') line.erase(0,1);
		}
		return types();
	};
	tokens["line"]=[](string& line){
		FILE* fp=pexpl(line).f;
		types t;
		t.ty='s';
		char buf[4096];
		if(fgets(buf,sizeof(buf),fp)){
			t.str=string(buf);
			if(!t.str.empty()&&t.str.back()=='\n')
				t.str.pop_back();
		}
		return t;
	};
	tokens["seek"]=[](string& line){
		FILE* fp=pexpl(line).f;
		int offset=pexpl(line)._int;
		int origin=SEEK_SET;
		if(line.find("cur")!=string::npos)origin=SEEK_CUR;
		else if(line.find("end")!=string::npos)origin=SEEK_END;
		fseek(fp,offset,origin);
		return types();
	};
	tokens["tag"]=[](string&){return types();};
	tokens["goto"]=[](string& line){
		ling=pexpl(line)._int;
		return types();
	};
	tokens["()"]=[](string& line){
		types t;
		t.ty='v';
		return t;
	};
	tokens["coro"]=[](string &line){
		stringstream ss(line);
		string str;
		ss>>str;
		pan:
		if(str[0]=='['){
			str=str.data()+1;
			goto pan;
		}
		types t=vmap[str];
		t.ty='C';
		return t;
	};
	tokens["del"]=[](string &line){
		stringstream ss(line);
		string str;
		ss>>str;
		pan:
		if(str[0]=='['){
			str=str.data()+1;
			goto pan;
		}
		vmap.erase(str);
		types t;
		t.ty='v';
		return t;
	};
	tokens["def"]=[](string &line){
		stringstream ss(line);
		string str,t2;
		ss>>str;
		getline(ss,t2);
		line=t2;
		pan:
		if(str[0]=='['){
			str=str.data()+1;
			goto pan;
		}
		types t;
		t.ty='b';
		t._int=(vmap.find(str)!=vmap.end());
		return t;
	};
	tokens["typeid"]=[](string &line){
		stringstream ss(line);
		string str,t2;
		ss>>str;
		getline(ss,t2);
		line=t2;
		pan:
		if(str[0]=='['){
			str=str.data()+1;
			goto pan;
		}
		types t;
		t.ty='c';
		t._int=vmap[str].ty;
		return t;
	};
}
//解释器启动! 
types explain(){
	types t;
	t.ty='v';
	int i=1;
	try{
	for(;ling<on&&i;ling++){
		string line=ops[ling]; // 创建行副本
		if(line.empty())continue;
		stringstream ss(line);
		pexpl(line);
		ss>>line;
		if(line=="while"||line=="until"){
			i++;
		}else if(line=="}"){
			i--;
		}
	}}catch(const r&){
		ling++;
		return ret;
	}
	return t;
}
types co_explain(int &ling){
	types t;
	t.ty='v';
	int i=1;
	try{
	for(;ling<on&&i;ling++){
		string line=ops[ling]; // 创建行副本
		if(line.empty())continue;
		stringstream ss(line);
		pexpl(line);
		ss>>line;
		if(line=="while"||line=="until"){
			i++;
		}else if(line=="}"){
			i--;
		}
	}}catch(const r&){
		ling++;
		return ret;
	}
	if(i==0)ling--;
	return t;
}

string temp;
string dirf;
map<string,vector<string>> pmap;
string trm(const string &str){
	string t;
	for(const auto &i:str){
		if(i=='{')break;
		t+=string(1,i);
	}
	return t;
}
void string_replace(string & strBig, const string & strsrc, const string &strdst)
{
	string::size_type pos = 0;
	string::size_type srclen = strsrc.size();
	string::size_type dstlen = strdst.size();
	while ((pos = strBig.find(strsrc, pos)) != string::npos)
	{
		// 如果能找到 pos         
		strBig.replace(pos, srclen, strdst);   
		pos += dstlen;   
	}
}

void reader(string name){
	ifstream f(name);
	while(getline(f,ops[on++])){
		stringstream ss(ops[on-1]);
		if(ss>>temp,temp=="func"){
			ss>>temp;
			temp=trm(temp);
			vmap[temp]._int=on;
			vmap[temp].ty='f';
			ss>>vmap[temp].str;
		}else if(temp=="Import"){
			ss>>temp;
			on--;
			reader(temp);
		}else if(temp=="tag"){
			ss>>temp;
			vmap[temp]._int=on;
			vmap[temp].ty='f';
		}else if(temp=="import"){
			ss>>temp;
			on--;
			reader(dirf+temp);
		}else if(temp=="pack"){
			on--;
			ss>>temp;
			temp=trm(temp);
			string t2,t3;
			int a=1;
			while(getline(f,t2)){
				stringstream ss(t2);
				ss>>t3;
				if(t3=="func"||t3=="while"||t3=="until"||t3=="if"){
					a++;
				}else if(t3=="}"){
					a--;
				}
				if(!a)break;
				pmap[temp].push_back(t2);
			}
		}else if(temp=="obj"){
			string t2,t3;
			ss>>temp>>t2;
			ops[on-1]="";
			for(const auto &a:pmap[temp]){
				t3=a;
				string_replace(t3,"self",t2);
				ops[on++]=t3;
				stringstream ss(t3);
				ss>>t3;
				if(t3=="func"){
					ss>>t3;
					t3=trm(t3);
					types t;
					t.ty='f';
					t._int=on;
					vmap[t3]=t;
				}
			}
		}
	}
}

int main(int ac,char **av){
    JANpost = av[0];
    size_t pos = JANpost.find_last_of("\\/");
    string exeDir = (pos != string::npos) ? JANpost.substr(0, pos + 1) : "";
    dirf = exeDir + "lib\\";
    init();
	bool b=0;
	cout<<"IJanus[版本0.1.1]";
	while(1){
		beg:
		cout<<"\n>\n";
		cin.sync();
		while(getline(cin,ops[on++]),1){
			if(ops[on-1]=="#end"){
				on--;
				break;
			}else if(ops[on-1]=="#clear"){
				vmap.clear();
				pmap.clear();
				on=0;
				ling=0;
				goto beg;
			}else if(ops[on-1]=="#show"){
				b=1;
			}else if(ops[on-1]=="#hide"){
				b=0;
			}else if(ops[on-1]=="#exit"){
				return 0;
			}
			stringstream ss(ops[on-1]);
			if(ss>>temp,temp=="func"){
				ss>>temp;
				temp=trm(temp);
				vmap[temp]._int=on;
				vmap[temp].ty='f';
				ss>>vmap[temp].str;
			}else if(temp=="Import"){
				ss>>temp;
				on--;
				reader(temp);
			}else if(temp=="tag"){
				ss>>temp;
				vmap[temp]._int=on;
				vmap[temp].ty='f';
			}else if(temp=="import"){
				ss>>temp;
				on--;
				reader(dirf+temp);
			}else if(temp=="pack"){
				on--;
				ss>>temp;
				temp=trm(temp);
				string t2,t3;
				int a=1;
				while(getline(cin,t2)){
					stringstream ss(t2);
					ss>>t3;
					if(t3=="func"||t3=="while"||t3=="until"||t3=="if"){
						a++;
					}else if(t3=="}"){
						a--;
					}
					if(!a)break;
					pmap[temp].push_back(t2);
				}
			}else if(temp=="obj"){
				string t2,t3;
				ss>>temp>>t2;
				ops[on-1]="";
				for(const auto &a:pmap[temp]){
					t3=a;
					string_replace(t3,"self",t2);
					ops[on++]=t3;
					stringstream ss(t3);
					ss>>t3;
					if(t3=="func"){
						ss>>t3;
						t3=trm(t3);
						types t;
						t.ty='f';
						t._int=on;
						vmap[t3]=t;
					}
				}
			}
		}
		cut();
		clock_t c=clock();
		if(b){
			cout<<"[Console]\n";
		}
		types t=explain();
		c=clock()-c;
		if(b){
			cout<<"\n--------------------------------\nProcess exited after "<<c/1000<<'.'<<c%1000<<" seconds with return value ";
			switch(t.ty){
				case 's': cout<<'\"'<<t.str<<'\"'; break;
				case 'c': cout<<'\''<<char(t._int)<<'\''; break;
				case 'i': cout<<t._int; break;
				case 'b': cout<<(t._int?"true":"false"); break;
				case 'v': cout<<"()"; break;
			}
			cout<<"\n";
		}
	}
}